home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / 051-060 / amok58 / realconversions2 / realconversions2.dok < prev    next >
Text File  |  1993-11-04  |  7KB  |  174 lines

  1. DEFINITION RealConversions2;
  2.  
  3. *********************************************************************
  4.  
  5. ACHTUNG: Dieses Modul funktioniert auch mit LONGREAL-Zahlen! Es wird
  6.          dabei die bedingte Compilation ausgenutzt. Wird das Modul
  7.          normal compiliert, ist Real=REAL. Wird aber bei der
  8.          Compilation im CLI die Variable LONGREAL gesetzt, so ist
  9.          Real=LONGREAL.
  10.  
  11.          Aufruf in CLI, um die LONGREAL-Version zu erzeugen:
  12.  
  13.          Oberon SET LONGREAL RealConversions2
  14.  
  15.          Es werden dann die Dateien LongRealConversion2.sym und
  16.          LongRealConversions2.obj erzeugt.
  17.  
  18. *********************************************************************
  19.  
  20.   PROCEDURE DeleteSpaces(VAR str:ARRAY OF CHAR);
  21.  
  22.   PROCEDURE StringToReal(str:ARRAY OF CHAR;
  23.                          VAR x:Real):BOOLEAN;
  24.  
  25.   PROCEDURE RealToString(x:Real;
  26.                          VAR str:ARRAY OF CHAR;
  27.                          gs,nks:INTEGER;expo,left:BOOLEAN):BOOLEAN;
  28.  
  29.  
  30. Die Prozedur StringToReal() wandelt eine als String vorliegende Zahl
  31. in eine (rechnerinterne) REAL- bzw. LONGREAL-Zahl um. RealToString()
  32. wandelt umgekehrt eine reelle Zahl von der rechnerinternen Darstellung
  33. in eine lesbare Zeichenkette um.
  34.  
  35. Was ist nun der Vorteil von RealConversions2 gegenüber dem Modul
  36. RealConversions, welches zum Amiga-Oberon-Compiler V2.0 mitgeliefert
  37. wurde?
  38.  
  39. Zuerst einmal ist das originale RealConversions bei der Umwandlung
  40. recht ungenau: Wandelt man eine n-stellige REAL-Zahl, welche als
  41. Zeichenkette vorliegt, in die rechnerinterne Darstellung und dann
  42. wieder zurückt in eine Zeichenkette, so bekommt man auch bei n<7 nicht
  43. immer die ursprüngliche Ziffernfolge. Außerdem gefällt mir das
  44. Zahlenformat, welches die originale Prozedur RealToString() liefert
  45. nicht übermäßig.
  46.  
  47. Nun zu der Beschreibung der beiden Prozeduren:
  48.  
  49. PROCEDURE StringToReal(str:ARRAY OF CHAR; VAR x:Real):BOOLEAN;
  50.  
  51. Die Zeichenkette str wird in die reelle Zahl x umgewandelt. Das
  52. Resultat ist TRUE, wenn die Zeichenkette folgender Gramatik
  53. entspricht:
  54.  
  55. digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9".
  56. sign  = ["+"|"-"].
  57. int   = {digit}.
  58. real  = sign int ["." int] [("E"|"e") sign int]
  59.  
  60. Die Zeichenkette darf KEINE Leerzeichen enthalten.
  61. Falls man Zeichenketten mit Leerzeichen verarbeiten will, kann man
  62. zuvor mit der Prozedur DeleteSpaces() die Leerzeichen entfernen.
  63.  
  64. Falls die Zahl den REAL- bzw. LONGREAL-Bereich überschreitet, wird
  65. FALSE zurückgegeben.
  66.  
  67. Beispiele:
  68.  
  69. Zeichenkette           Zahl          Resultat
  70.  
  71. ""                     0.0           TRUE
  72. "1"                    1.0           TRUE
  73. "3.84"                 3.84          TRUE
  74. "-.34532"             -0.34532       TRUE
  75. "23."                  23.0          TRUE
  76. ".E"                   0.0           TRUE
  77. "-34.5E+12"           -3.45E13       TRUE
  78.  
  79. "3,4"                  ---           FALSE
  80. "--3"                  ---           FALSE
  81. "3.45.E3"              ---           FALSE
  82. "9.8E372"              ---           FALSE
  83.  
  84.  
  85. PROCEDURE RealToString(x:Real;
  86.                        VAR str:ARRAY OF CHAR;
  87.                        gs,nks:INTEGER;expo,left:BOOLEAN):BOOLEAN;
  88.  
  89. RealToString() wandelt die Zahl x in einen String um. Dabei gibt gs
  90. an, mit wie viel signifikanten Ziffern die Zahl dargestellt werden
  91. soll. Folgende Zahlen haben je 5 signifikante Ziffern:
  92.  
  93. 12345
  94. 123.45
  95. 1.2345E-13
  96. 0.000000054321
  97.  
  98. Die führenden Nullen bei der letzten Zahl sind keine signifikanten
  99. Ziffern, da 0.000000054321 = 5.4321E-8. Der Skalierungsfaktor E-8 ist
  100. nur durch das verwendete Maßsystem bedingt und hat mit der Genauigkeit
  101. der Zahl nichts zu tun:
  102.  
  103. 0.012 m   =12E-3 m =  12 mm
  104.  
  105. Obige Längenangaben in Metern oder Millimetern sind also gleichwertig,
  106. die Genauigkeit ist je zweistellig bzw. 1/100 = 1%
  107.  
  108.  
  109. Manchmal möchte man die Zahl der Nachkommastellen beschränken,
  110. beispielsweise will man bei Preisangabe in DM nicht mehr als 2
  111. Nachkommastellen haben. Daher kann man mit nks die Zahl der
  112. Nachkommastellen beschränken. Ist nks=n, so bekommt der String maximal
  113. n Nachkommastellen. Hat x mehr Vorkommastellen als gs erlaubt, so wird
  114. automatisch die wissenschaftliche Zahlendarstellung mit Exponent
  115. verwendet. (xEnn entspricht dabei x * 10^nn.) Ist expo=TRUE, wird
  116. diese wissenschaftliche Zahlendarstellung stets verwendet. Ist
  117. left=TRUE, so wird die Zahl linksbündig in str eingetragen,
  118. anderenfalls rechtsbündig. Die Zahl wird wie üblich gerundet, d.h.
  119. wenn die Ziffer, welche der letzten sichtbaren Dezimalstelle folgen
  120. würde, größer oder gleich fümf ist, wird aufgerundet.
  121.  
  122.  123.456  ==>  123.46
  123. -34.9973  ==> -35.00
  124.  
  125. Eine Besonderheit gibt es noch: Ist |x| < 1, so wird x mit weniger als
  126. gs signifikanten Ziffern dargestellt. Der Grund ist, daß viele Leute
  127. statt der vierstelligen Zahl 7.894E-11 lieber 0.000 lesen. Will man
  128. dagegen die eigentlich korrekte Darstellung 7.894E-11 erhalten, so
  129. muß der Prozeduraufruf folgendermaßen aussehen:
  130.  
  131. ok:=RealToString(zahl,str,4,4, ABS(x)<=1, left);
  132.  
  133. Ist |x|<=1, so wird automatisch die wissenschaftliche Darstellung
  134. gewählt.
  135.  
  136. Das Resultat ist TRUE, wenn die Zahl in str Platz fand.
  137.  
  138.  
  139. Zum Schluß noch etwas zur Genauigkeit:
  140. Ich habe versucht, die Umwandlungsfehler, welche durch die endliche
  141. Rechengenauigkeit entstehen, so gering wie möglich zu halten.
  142. Insbesondere habe ich daher auf die Benutzung des Logarithmus und der
  143. Exponentialfunktion verzichtet. Bei der Prozedur StringToReal() müssen
  144. die einzelnen Zehnerpotenzen aufsummiert werden. Ich beginne die
  145. Summation mit den kleinsten Potenzen. Dies ist zwar etwas
  146. umständlicher, sollte aber eine größere nummerische Genauigkeit
  147. ergeben. Selbstverständlich habe ich auch versucht, die Anzahl der
  148. Rechenoperationen so gering wie möglich zu halten, da jede Operation
  149. den nummerischen Fehler vergrößert.
  150.  
  151.  
  152. Mit den beiliegenden Testprogrammen LRCTest (für LONGREAL) und RCTest
  153. (für REAL), welche eine Zeichenkette einlesen, diese mit
  154. StringToReal() in eine Real-Zahl und dann mit RealToString() wieder in
  155. eine Zeichenkette umwandeln, kann man die Genauigkeit testen. Bei
  156. REAL-Zahlen (eigentlich sind es FFP-Zahlen) wird fast eine
  157. siebenstellige Genauigkeit erreicht. ( Nur fast, denn z.B 34 liefert
  158. 34.00001 ). Benutzt man LONGREAL-Zahlen, wird eine 14-stellige
  159. Genauigkeit erreicht.
  160.  
  161. Alle Angaben selbstverständlich ohne Gewähr!
  162.  
  163.  
  164. PS: Bei der  Version 2.0 des Amiga-Oberon-Compilers führt das Rechnen mit
  165.     REAL-Konstanten manchmal zu recht großen nummerischen Ungenauigkeiten.
  166.     Beispielsweise ergibt die Multiplikation mit 1.0E-1 einen größeren
  167.     nummerischen Fehler als die Division durch 10. Ich habe daher
  168.     weitgehend auf die Benutzung von REAL-Konstanten verzichtet.
  169.  
  170.  
  171. Stefan Salewski, 12.8.91
  172.  
  173.  
  174.